﻿using CommunicationLib.Enums;
using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PlcLib.Model
{
    /// <summary>
    /// 下发数据的指令
    /// </summary>
    public struct Command
    {
        public int WordAddress { get; private set; } // 字地址
      
        public int Length { get; private set; }// 长度，单位为字(Word)或位(Bit)，一个字=2个字节
        public DataType DataType { get; private set; } // 数据类型
        public OperactorMode OperactorMode { get; private set; } // 操作模式
        public AreaType AreaType { get; private set; } // 区域类型
        public byte BitAddress { get; private set; } // 位地址，默认为0

        public Command(int wordaddress, int length, DataType dataType, OperactorMode operactorMode, AreaType areaType, byte bitAddress = 0)
        {
            WordAddress = wordaddress;
            Length = length;
            DataType = dataType;
            OperactorMode = operactorMode;
            AreaType = areaType;
            BitAddress = bitAddress;
        }
        /// <summary>
        /// 区域 
        /// </summary>
        public byte Area
        {
            get 
            { 
                byte area = 0;
                switch (AreaType)
                {
                    case AreaType.AR:area = (byte)(DataType == DataType.Bit ? 0x33 : 0xB3); 
                        break;
                    case AreaType.HR:area = (byte)(DataType == DataType.Bit ? 0x32 : 0xB2);
                        break;
                    case AreaType.WR:area = (byte)(DataType == DataType.Bit ? 0x31 : 0xB1);
                        break;
                    case AreaType.CIO:area = (byte)(DataType == DataType.Bit ? 0x30 : 0xB0);
                        break;
                    case AreaType.DM: area = (byte)(DataType == DataType.Bit ? 0x02 : 0x82);
                        break;
                }
                return area;
            }
        }
        /// <summary>
        /// 获取 读取指令的字节数组
        /// </summary>
        /// <param name="net"></param>
        /// <param name="CommandId"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public byte[] GetReadBuffer(Net net,long CommandId)
        {
            if (OperactorMode!=OperactorMode.Read)
            {
                throw new Exception("读取plc时候OperactorMode模式应为read");
            }
            int dataByteLength = 26;// 4位数据头 + 4位数据长度 + 1位区域 + 2位字地址 + 2位长度 + 1位操作模式 + 1位位地址 + 8位CRC校验
            byte[] sendBuffer = new byte[8 + dataByteLength];

            //4位数据头
            sendBuffer[0] = 0x46; // f
            sendBuffer[1] = 0x49; // a
            sendBuffer[2] = 0x4e; // n
            sendBuffer[3] = 0x53; // s

            // 4位数据长度
            byte[] lengths = BitConverter.GetBytes(dataByteLength).Reverse().ToArray();

            sendBuffer[4] = lengths[0];
            sendBuffer[5] = lengths[1];
            sendBuffer[6] = lengths[2];
            sendBuffer[7] = lengths[3];

            //数据体
            sendBuffer[8] = 0x00;
            sendBuffer[9] = 0x00;
            sendBuffer[10] = 0x00;
            sendBuffer[11] = 0x00;

            //错误检测码
            sendBuffer[12] = 0x00;
            sendBuffer[13] = 0x00;
            sendBuffer[14] = 0x00;
            sendBuffer[15] = 0x00;

            //
            sendBuffer[16] = 0x80;//icf
            sendBuffer[17] = 0x00;//rsv
            sendBuffer[18] = 0x02;//gct
            sendBuffer[19] = 0x00;//dna

            //
            sendBuffer[20] = net.ServerLastNode;//PLC ip地址的最后一个节点
            sendBuffer[21] = 0x00;//rsv
            sendBuffer[22] = 0x02;//gct
            sendBuffer[23] = net.ClientLastNode;//上位机ip地址的最后一个节点

            //
            sendBuffer[24] = 0x00;//SA2
            sendBuffer[25] = (byte)CommandId;//SID -> 命令编号
            sendBuffer[26] = 0x01;//读取命令
            sendBuffer[27] = 0x01;//读取长度

            sendBuffer[28] = Area;//区域
            sendBuffer[29] = (byte)((byte)(WordAddress>>8)&0xFF);//字地址高8位
            sendBuffer[30] = (byte)(WordAddress & 0xFF);//字地址低8位
            sendBuffer[31] = BitAddress;//位地址 0~15

            sendBuffer[32] = (byte)((byte)(Length >> 8) & 0xFF);//长度位移8个，长度进行相位与
            sendBuffer[33] = (byte)(Length & 0xFF);//长度低8位
            return sendBuffer;
        }

        public byte[] GetWriteBuffer(Net net, long commandId, int data)
        {
            return GetWriteBuffer(net, commandId, new List<int> { data });
        }

        public byte[] GetWriteBuffer(Net net, long commandId, List<int> data)
        {
           if(OperactorMode != OperactorMode.Write)
            {
                throw new Exception("写入plc时候OperactorMode模式应为write");
            }
           if(data == null || data.Count == 0)
            {
                throw new Exception("写入plc时候data不能为空");
            }
           if (data.Count > 100)
            {
                throw new Exception($"写入plc时候data长度超过了100，请检查");
            }
            ushort[] writeArray;// 写入数据数组
            if (DataType == DataType.WordBCD)
            {
                if (data[0] < 0 || data[0] > 9999)
                {
                    throw new Exception("写入plc时候WordBCD不符合要求");
                }
      
                writeArray = new ushort[] { (ushort)data[0] };// BCD码只取第一个数据
                writeArray[0] = ushort.Parse(writeArray[0].ToString(), NumberStyles.AllowHexSpecifier);// 将十进制转换为BCD码
            }
            else
            {
                //适配任意写入长度，以Length属性为准
                var array = data.ToArray();
                var tempArray = new ushort[array.Length * 2];// 临时数组，长度为原数组的两倍
                for (int i = 0; i < array.Length; i++)
                {
                    tempArray[i * 2] = (ushort)(data[i] & 0xffff); // 高位
                    tempArray[i * 2 + 1] = (ushort)((data[i] >> 16) & 0xffff);// 低位
                }

                writeArray = new ushort[Length ];// 写入数据数组
                if (tempArray.Length < writeArray.Length)
                {
                    throw new Exception("写入plc时,写入实际数据的长度和预设长度不一致");
                }
                for (int i = 0; i < writeArray.Length; i++)
                {
                    writeArray[i] = tempArray[i]; // 将临时数组的值赋给写入数据数组
                }
            }
            var dataArray = writeArray;// 获取写入数据数组
            int dataByteLength = (DataType == DataType.Bit ? 1 : 2) * dataArray.Length + 26;
            byte[] sendBuffer = new byte[8 + dataByteLength];
            //4位数据头
            sendBuffer[0] = 0x46; // f
            sendBuffer[1] = 0x49; // a
            sendBuffer[2] = 0x4e; // n
            sendBuffer[3] = 0x53; // s

            // 4位数据长度
            byte[] lengths = BitConverter.GetBytes(dataByteLength).Reverse().ToArray();

            sendBuffer[4] = lengths[0];
            sendBuffer[5] = lengths[1];
            sendBuffer[6] = lengths[2];
            sendBuffer[7] = lengths[3];

            //数据体
            sendBuffer[8] = 0x00;
            sendBuffer[9] = 0x00;
            sendBuffer[10] = 0x00;
            sendBuffer[11] = 0x00;

            //错误检测码
            sendBuffer[12] = 0x00;
            sendBuffer[13] = 0x00;
            sendBuffer[14] = 0x00;
            sendBuffer[15] = 0x00;

            //
            sendBuffer[16] = 0x80;//icf
            sendBuffer[17] = 0x00;//rsv
            sendBuffer[18] = 0x02;//gct
            sendBuffer[19] = 0x00;//dna

            //
            sendBuffer[20] = net.ServerLastNode;//PLC ip地址的最后一个节点
            sendBuffer[21] = 0x00;//rsv
            sendBuffer[22] = 0x02;//gct
            sendBuffer[23] = net.ClientLastNode;//上位机ip地址的最后一个节点

            //
            sendBuffer[24] = 0x00;//SA2
            sendBuffer[25] = (byte)commandId;//SID -> 命令编号
            sendBuffer[26] = 0x01;//写命令
            sendBuffer[27] = 0x02;//写入长度

            sendBuffer[28] = Area;//区域
            sendBuffer[29] = (byte)((byte)(WordAddress >> 8) & 0xFF);//字地址高8位
            sendBuffer[30] = (byte)(WordAddress & 0xFF);//字地址低8位
            sendBuffer[31] = BitAddress;//位地址 0~15

            int count = dataArray.Length;
            sendBuffer[32] = (byte)((byte)(count >> 8) & 0xFF);//长度位移8个，长度进行相位与
            sendBuffer[33] = (byte)(count & 0xFF);//长度低8位
            if (DataType == DataType.Bit)
            {
                    sendBuffer[34 ] = (byte)(dataArray[0] & 0x01); // 位数据
            }
            else
            {
                // 将写入的数据赋到byte数组中
                for (int i = 0; i < dataArray.Length; i++)
                {
                    sendBuffer[34 + i * 2] = (byte)((dataArray[i] >> 8) & 0xFF); // 高位
                    sendBuffer[34 + 1 + i * 2] = (byte)(dataArray[i] & 0xFF); // 低位
                }
            }

            return sendBuffer;
        }


        //支持泛型数据写入方法
        public byte[] GetWriteBuffer<T>(Net net, long commandId, T data)
        {
          
            if (DataType == DataType.Bit && (BitAddress < 0 || BitAddress > 15))
            {
               throw new Exception("位地址BitAddress必须在0~15之间");
            }
            byte[] result= new byte[0];
            Type type = typeof(T);
            switch (type.FullName)//获取类型的全民
            {
                //单个变量
                case "System.Boolean":
                    result = GetBooleanBytes(net, commandId, (bool)(object)data);
                    break;
              
                case "System.Single":
                    float[] floatArray = new float[] { (float)(object)(data) };
                    result = GetSingleBytes(net, commandId, floatArray);
                    break;
                case "System.Int16":
                    short[] intArray = new short[] {(short)(object)(data) };
                    result = GetInt16Bytes(net, commandId, intArray);
                    break;
                case "System.Int32":
                    int[] intArray32 = new int[] { (int)(object)(data) };
                    result = GetInt32Bytes(net, commandId, intArray32);
                    break;
                case "System.UInt16":
                    ushort[] ushorttArray = new ushort[] { (ushort)(object)(data) };
                    result = GetUInt16Bytes(net, commandId, ushorttArray);
                    break;
                case "System.UInt32":
                    uint[] uintArray32 = new uint[] { (uint)(object)(data) };
                    result = GetUInt32Bytes(net, commandId, uintArray32);
                    break;

                ////数组变量
            
                case "System.Single[]":
                    result = GetSingleBytes(net, commandId, (float[])(object)data);
                    break;
                case "System.Int16[]":
                    result = GetInt16Bytes(net, commandId, (short[])(object)data);
                    break;
                case "System.UInt16[]":
                    result = GetUInt16Bytes(net, commandId, (ushort[])(object)data);
                    break;
                case "System.Int32[]":
                    result = GetInt32Bytes(net, commandId, (int[])(object)data);
                    break;
                case "System.UInt32[]":
                    result = GetUInt32Bytes(net, commandId, (uint[])(object)data);
                    break;

            }
            return result;

          
        }

        private byte[] GetSingleBytes(Net net, long commandId, float[] data)
        {
            if (data == null || data.Length == 0)
            {
                throw new Exception("float数组不能为空");
            }
            if (DataType == DataType.Bit)
            {
                throw new Exception("暂不支持bit写入");
            }
            if (DataType == DataType.WordBCD)
            {
                throw new Exception("暂不支持float写入BCD");
            }
            var source = new byte[data.Length * 4]; // 每个float占4个字节
            for (int i = 0; i < data.Length; i++)
            {
                var array = BitConverter.GetBytes(data[i]);
                //高低位转换
                for (int j = 0; j < array.Length; j += 2)
                {
                    (array[j], array[j + 1]) = (array[j + 1], array[j]);
                }
                source[i * 4] = array[0];// 高位
                source[i * 4 + 1] = array[1];// 第二位
                source[i * 4 + 2] = array[2];// 第三位
                source[i * 4 + 3] = array[3];// 低位

            }
            var dataArray = source;
            var dataByteLength = dataArray.Length + 26;// 4位数据头 + 4位数据长度 + 1位区域 + 2位字地址 + 2位长度 + 1位操作模式 + 1位位地址 + 8位CRC校验
            byte[] sendBuffer = new byte[8 + dataByteLength];// 8位头部 + 数据长度 + 数据体 + CRC校验



            //4位数据头
            sendBuffer[0] = 0x46; // f
            sendBuffer[1] = 0x49; // i
            sendBuffer[2] = 0x4e; // n
            sendBuffer[3] = 0x53; // s

            // 4位数据长度
            byte[] lengths = GetByteLengt(dataByteLength);// 将长度转换为字节数组并反转顺序

            sendBuffer[4] = lengths[0];
            sendBuffer[5] = lengths[1];
            sendBuffer[6] = lengths[2];
            sendBuffer[7] = lengths[3];

            //数据体
            sendBuffer[8] = 0x00;
            sendBuffer[9] = 0x00;
            sendBuffer[10] = 0x00;
            sendBuffer[11] = 0x02;

            //错误检测码
            sendBuffer[12] = 0x00;
            sendBuffer[13] = 0x00;
            sendBuffer[14] = 0x00;
            sendBuffer[15] = 0x00;

            //
            sendBuffer[16] = 0x80;//icf
            sendBuffer[17] = 0x00;//rsv
            sendBuffer[18] = 0x02;//gct
            sendBuffer[19] = 0x00;//dna

            //
            sendBuffer[20] = net.ServerLastNode;//PLC ip地址的最后一个节点
            sendBuffer[21] = 0x00;//DN2
            sendBuffer[22] = 0x02;//SNA
            sendBuffer[23] = net.ClientLastNode;//上位机ip地址的最后一个节点

            //
            sendBuffer[24] = 0x00;//SA2
            sendBuffer[25] = (byte)commandId;//SID -> 命令编号
            sendBuffer[26] = 0x01;//读取命令
            sendBuffer[27] = 0x01;//读取长度

            sendBuffer[28] = Area;//区域
            sendBuffer[29] = (byte)((byte)(WordAddress >> 8) & 0xFF);//字地址高8位
            sendBuffer[30] = (byte)(WordAddress & 0xFF);//字地址低8位
            sendBuffer[31] = BitAddress;//位地址 0~15

            int count = dataArray.Length;// 每个int占4个字节
            sendBuffer[32] = (byte)((count >> 8) & 0xFF);//长度位移8个，长度进行相位与
            sendBuffer[33] = (byte)(count & 0xFF);//长度低8位

            // 将数据写入到发送dataArray【】后面
            int index = 0;
            for (int i = 0; i < sendBuffer.Length; i++)
            {
                sendBuffer[i] = dataArray[index++];
            }
            return sendBuffer;
        }

        private byte[] GetUInt32Bytes(Net net, long commandId, uint[] data)
        {
            if (data == null || data.Length == 0)
            {
                throw new Exception("uint数组不能为空");
            }
            if (DataType == DataType.Bit)
            {
                throw new Exception("暂不支持bit写入");
            }
            if (DataType == DataType.WordBCD)
            {
                for (int i = 0; i < data.Length; i++)
                {
                    data[i] = (uint)int.Parse(data[i].ToString(), NumberStyles.AllowHexSpecifier);
                }
            }
            var source = new byte[data.Length * 4];
            for (int i = 0; i < data.Length; i++)
            {
                var array = BitConverter.GetBytes(data[i]);
                //高低位转换
                for (int j = 0; j < array.Length; j += 2)
                {
                    (array[j], array[j + 1]) = (array[j + 1], array[j]);
                }
                source[i * 4] = array[0];// 高位
                source[i * 4 + 1] = array[1];// 第二位
                source[i * 4 + 2] = array[2];// 第三位
                source[i * 4 + 3] = array[3];// 低位

            }
            var dataArray = source;
            var dataByteLength = dataArray.Length + 26;// 4位数据头 + 4位数据长度 + 1位区域 + 2位字地址 + 2位长度 + 1位操作模式 + 1位位地址 + 8位CRC校验
            byte[] sendBuffer = new byte[8 + dataByteLength];// 8位头部 + 数据长度 + 数据体 + CRC校验



            //4位数据头
            sendBuffer[0] = 0x46; // f
            sendBuffer[1] = 0x49; // i
            sendBuffer[2] = 0x4e; // n
            sendBuffer[3] = 0x53; // s

            // 4位数据长度
            byte[] lengths = GetByteLengt(dataByteLength);// 将长度转换为字节数组并反转顺序

            sendBuffer[4] = lengths[0];
            sendBuffer[5] = lengths[1];
            sendBuffer[6] = lengths[2];
            sendBuffer[7] = lengths[3];

            //数据体
            sendBuffer[8] = 0x00;
            sendBuffer[9] = 0x00;
            sendBuffer[10] = 0x00;
            sendBuffer[11] = 0x02;

            //错误检测码
            sendBuffer[12] = 0x00;
            sendBuffer[13] = 0x00;
            sendBuffer[14] = 0x00;
            sendBuffer[15] = 0x00;

            //
            sendBuffer[16] = 0x80;//icf
            sendBuffer[17] = 0x00;//rsv
            sendBuffer[18] = 0x02;//gct
            sendBuffer[19] = 0x00;//dna

            //
            sendBuffer[20] = net.ServerLastNode;//PLC ip地址的最后一个节点
            sendBuffer[21] = 0x00;//DN2
            sendBuffer[22] = 0x02;//SNA
            sendBuffer[23] = net.ClientLastNode;//上位机ip地址的最后一个节点

            //
            sendBuffer[24] = 0x00;//SA2
            sendBuffer[25] = (byte)commandId;//SID -> 命令编号
            sendBuffer[26] = 0x01;//读取命令
            sendBuffer[27] = 0x01;//读取长度

            sendBuffer[28] = Area;//区域
            sendBuffer[29] = (byte)((byte)(WordAddress >> 8) & 0xFF);//字地址高8位
            sendBuffer[30] = (byte)(WordAddress & 0xFF);//字地址低8位
            sendBuffer[31] = BitAddress;//位地址 0~15

            int count = dataArray.Length;// 每个int占4个字节
            sendBuffer[32] = (byte)((byte)(count >> 8) & 0xFF);//长度位移8个，长度进行相位与
            sendBuffer[33] = (byte)(count & 0xFF);//长度低8位

            // 将数据写入到发送dataArray【】后面
            int index = 0;
            for (int i = 0; i < sendBuffer.Length; i++)
            {
                sendBuffer[i] = dataArray[index++];
            }
            return sendBuffer;
        }

        private byte[] GetInt32Bytes(Net net, long commandId, int[] data)
        {
            if (data == null || data.Length == 0)
            {
                throw new Exception("int数组不能为空");
            }
            if (DataType == DataType.Bit)
            {
                throw new Exception("暂不支持bit写入");
            }
            if(DataType == DataType.WordBCD)
            {
                for (int i = 0; i < data.Length; i++)
                {
                    data[i] = int.Parse(data[i].ToString(), NumberStyles.AllowHexSpecifier);
                }
            }
            var source = new byte[data.Length * 4];
            for (int i = 0; i < data.Length; i++)
            {
                var array = BitConverter.GetBytes(data[i]);
                //高低位转换
                for (int j = 0; j < array.Length; j += 2)
                {
                    (array[j], array[j + 1]) = (array[j + 1], array[j]);
                }
                source[i * 4] =array[0];// 高位
                source[i * 4 + 1] = array[1];// 第二位
                source[i * 4 + 2] = array[2];// 第三位
                source[i * 4 + 3] = array[3];// 低位

            }
            var dataArray = source;
            var dataByteLength = dataArray.Length + 26;// 4位数据头 + 4位数据长度 + 1位区域 + 2位字地址 + 2位长度 + 1位操作模式 + 1位位地址 + 8位CRC校验
            byte[] sendBuffer = new byte[8 + dataByteLength];// 8位头部 + 数据长度 + 数据体 + CRC校验



            //4位数据头
            sendBuffer[0] = 0x46; // f
            sendBuffer[1] = 0x49; // i
            sendBuffer[2] = 0x4e; // n
            sendBuffer[3] = 0x53; // s

            // 4位数据长度
            byte[] lengths = GetByteLengt(dataByteLength);// 将长度转换为字节数组并反转顺序

            sendBuffer[4] = lengths[0];
            sendBuffer[5] = lengths[1];
            sendBuffer[6] = lengths[2];
            sendBuffer[7] = lengths[3];

            //数据体
            sendBuffer[8] = 0x00;
            sendBuffer[9] = 0x00;
            sendBuffer[10] = 0x00;
            sendBuffer[11] = 0x02;

            //错误检测码
            sendBuffer[12] = 0x00;
            sendBuffer[13] = 0x00;
            sendBuffer[14] = 0x00;
            sendBuffer[15] = 0x00;

            //
            sendBuffer[16] = 0x80;//icf
            sendBuffer[17] = 0x00;//rsv
            sendBuffer[18] = 0x02;//gct
            sendBuffer[19] = 0x00;//dna

            //
            sendBuffer[20] = net.ServerLastNode;//PLC ip地址的最后一个节点
            sendBuffer[21] = 0x00;//DN2
            sendBuffer[22] = 0x02;//SNA
            sendBuffer[23] = net.ClientLastNode;//上位机ip地址的最后一个节点

            //
            sendBuffer[24] = 0x00;//SA2
            sendBuffer[25] = (byte)commandId;//SID -> 命令编号
            sendBuffer[26] = 0x01;//读取命令
            sendBuffer[27] = 0x01;//读取长度

            sendBuffer[28] = Area;//区域
            sendBuffer[29] = (byte)((byte)(WordAddress >> 8) & 0xFF);//字地址高8位
            sendBuffer[30] = (byte)(WordAddress & 0xFF);//字地址低8位
            sendBuffer[31] = BitAddress;//位地址 0~15

            int count = dataArray.Length ;// 每个int占4个字节
            sendBuffer[32] = (byte)((byte)(count >> 8) & 0xFF);//长度位移8个，长度进行相位与
            sendBuffer[33] = (byte)(count & 0xFF);//长度低8位

            // 将数据写入到发送dataArray【】后面
           int index = 0;
            for (int i = 0; i < sendBuffer.Length; i++)
            {
                sendBuffer[i] = dataArray[index++];
            }
            return sendBuffer;
        }

        private byte[] GetBooleanBytes(Net net, long commandId, bool data)
        {
           var dataArray = new byte[] { (byte)(data ? 1 : 0) };// 获取写入数据数组
           var dataByteLength = dataArray.Length + 26;// 4位数据头 + 4位数据长度 + 1位区域 + 2位字地址 + 2位长度 + 1位操作模式 + 1位位地址 + 8位CRC校验
           byte[] sendBuffer = new byte[8 + dataByteLength];// 8位头部 + 数据长度 + 数据体 + CRC校验

           //4位数据头
           sendBuffer[0] = 0x46; // f
           sendBuffer[1] = 0x49; // i
           sendBuffer[2] = 0x4e; // n
           sendBuffer[3] = 0x53; // s

           // 4位数据长度
           byte[] lengths = GetByteLengt(dataByteLength);// 将长度转换为字节数组并反转顺序

           sendBuffer[4] = lengths[0];
           sendBuffer[5] = lengths[1];
           sendBuffer[6] = lengths[2];
           sendBuffer[7] = lengths[3];

           //数据体
           sendBuffer[8] = 0x00;
           sendBuffer[9] = 0x00;
           sendBuffer[10] = 0x00;
           sendBuffer[11] = 0x02;

           //错误检测码
           sendBuffer[12] = 0x00;
           sendBuffer[13] = 0x00;
           sendBuffer[14] = 0x00;
           sendBuffer[15] = 0x00;

           //
           sendBuffer[16] = 0x80;//icf
           sendBuffer[17] = 0x00;//rsv
           sendBuffer[18] = 0x02;//gct
           sendBuffer[19] = 0x00;//dna

           //
           sendBuffer[20] = net.ServerLastNode;//PLC ip地址的最后一个节点
           sendBuffer[21] = 0x00;//DN2
           sendBuffer[22] = 0x02;//SNA
           sendBuffer[23] = net.ClientLastNode;//上位机ip地址的最后一个节点

           //
           sendBuffer[24] = 0x00;//SA2
           sendBuffer[25] = (byte)commandId;//SID -> 命令编号
           sendBuffer[26] = 0x01;//读取命令
           sendBuffer[27] = 0x01;//读取长度

           sendBuffer[28] = Area;//区域
           sendBuffer[29] = (byte)((byte)(WordAddress >> 8) & 0xFF);//字地址高8位
           sendBuffer[30] = (byte)(WordAddress & 0xFF);//字地址低8位
           sendBuffer[31] = BitAddress;//位地址 0~15

           sendBuffer[32] = (byte)((byte)(Length >> 8) & 0xFF);//长度位移8个，长度进行相位与
           sendBuffer[33] = (byte)(Length & 0xFF);//长度低8位

            // 将数据写入到发送dataArray【】后面
            sendBuffer[34] = dataArray[0];
            return sendBuffer;
        }

        private byte[] GetUInt16Bytes(Net net, long commandId, ushort[] data)
        {
            if (data == null || data.Length == 0)
            {
                throw new Exception("uint数组不能为空");
            }
            if (DataType == DataType.Bit)
            {
                throw new Exception("暂不支持bit写入");
            }
            if (DataType == DataType.WordBCD)
            {
                for (int i = 0; i < data.Length; i++)
                {
                    data[i] = ushort.Parse(data[i].ToString(), NumberStyles.AllowHexSpecifier);
                }
            }
            var source = new byte[data.Length * 2];
            for (int i = 0; i < data.Length; i++)
            {
                var array = BitConverter.GetBytes(data[i]);
                //高低位转换
                for (int j = 0; j < array.Length; j += 2)
                {
                    byte temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }
                source[i * 2] = array[0];// 高位
                source[i * 2 + 1] = array[1];// 低位

            }
            var dataArray = source;
            var dataByteLength = dataArray.Length + 26;// 4位数据头 + 4位数据长度 + 1位区域 + 2位字地址 + 2位长度 + 1位操作模式 + 1位位地址 + 8位CRC校验
            byte[] sendBuffer = new byte[8 + dataByteLength];// 8位头部 + 数据长度 + 数据体 + CRC校验

            //4位数据头
            sendBuffer[0] = 0x46; // f
            sendBuffer[1] = 0x49; // i
            sendBuffer[2] = 0x4e; // n
            sendBuffer[3] = 0x53; // s

            // 4位数据长度
            byte[] lengths = GetByteLengt(dataByteLength);// 将长度转换为字节数组并反转顺序

            sendBuffer[4] = lengths[0];
            sendBuffer[5] = lengths[1];
            sendBuffer[6] = lengths[2];
            sendBuffer[7] = lengths[3];

            //数据体
            sendBuffer[8] = 0x00;
            sendBuffer[9] = 0x00;
            sendBuffer[10] = 0x00;
            sendBuffer[11] = 0x02;

            //错误检测码
            sendBuffer[12] = 0x00;
            sendBuffer[13] = 0x00;
            sendBuffer[14] = 0x00;
            sendBuffer[15] = 0x00;

            //
            sendBuffer[16] = 0x80;//icf
            sendBuffer[17] = 0x00;//rsv
            sendBuffer[18] = 0x02;//gct
            sendBuffer[19] = 0x00;//dna

            //
            sendBuffer[20] = net.ServerLastNode;//PLC ip地址的最后一个节点
            sendBuffer[21] = 0x00;//DN2
            sendBuffer[22] = 0x02;//SNA 
            sendBuffer[23] = net.ClientLastNode;//上位机ip地址的最后一个节点

            //
            sendBuffer[24] = 0x00;//SA2
            sendBuffer[25] = (byte)commandId;//SID -> 命令编号
            sendBuffer[26] = 0x01;//读取命令
            sendBuffer[27] = 0x01;//读取长度

            sendBuffer[28] = Area;//区域
            sendBuffer[29] = (byte)((byte)(WordAddress >> 8) & 0xFF);//字地址高8位
            sendBuffer[30] = (byte)(WordAddress & 0xFF);//字地址低8位
            sendBuffer[31] = BitAddress;//位地址 0~15

            sendBuffer[32] = (byte)((byte)(Length >> 8) & 0xFF);//长度位移8个，长度进行相位与
            sendBuffer[33] = (byte)(Length & 0xFF);//长度低8位

            // 将数据写入到发送byte【】后面
            int index = 0;
            for (int i = 0; i < sendBuffer.Length; i++)
            {
                sendBuffer[i] = dataArray[index++];
            }
            return sendBuffer;
        }

        private byte[] GetInt16Bytes(Net net,long commandId, short[] data)
        {
            if (data == null || data.Length == 0)
            {
                throw new Exception("short数组不能为空");
            }
            if (DataType == DataType.Bit)
            {
                throw new Exception("暂不支持bit写入");
            }
            if (DataType == DataType.WordBCD)
            {
                for (int i = 0; i < data.Length; i++)
                {
                    data[i] = short.Parse(data[i].ToString(), NumberStyles.AllowHexSpecifier);
                }
            } 
            var source = new byte[data.Length * 2];
            for (int i = 0; i < data.Length; i++)
            {
                var array = BitConverter.GetBytes(data[i]);
                //高低位转换
                for (int j = 0; j < array.Length; j += 2)
                {
                    byte temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }
                source[i * 2] = array[0];// 高位
                source[i * 2 + 1] = array[1];// 低位

            }
            var dataArray = source;
            var dataByteLength =dataArray.Length + 26;// 4位数据头 + 4位数据长度 + 1位区域 + 2位字地址 + 2位长度 + 1位操作模式 + 1位位地址 + 8位CRC校验
            byte[] sendBuffer = new byte[8 + dataByteLength];// 8位头部 + 数据长度 + 数据体 + CRC校验
           
            //4位数据头
            sendBuffer[0] = 0x46; // f
            sendBuffer[1] = 0x49; // i
            sendBuffer[2] = 0x4e; // n
            sendBuffer[3] = 0x53; // s

            // 4位数据长度
            byte[] lengths = GetByteLengt(dataByteLength);// 将长度转换为字节数组并反转顺序

            sendBuffer[4] = lengths[0];
            sendBuffer[5] = lengths[1];
            sendBuffer[6] = lengths[2];
            sendBuffer[7] = lengths[3];

            //数据体
            sendBuffer[8] = 0x00;
            sendBuffer[9] = 0x00;
            sendBuffer[10] = 0x00;
            sendBuffer[11] = 0x02;

            //错误检测码
            sendBuffer[12] = 0x00;
            sendBuffer[13] = 0x00;
            sendBuffer[14] = 0x00;
            sendBuffer[15] = 0x00;

            //
            sendBuffer[16] = 0x80;//icf
            sendBuffer[17] = 0x00;//rsv
            sendBuffer[18] = 0x02;//gct
            sendBuffer[19] = 0x00;//dna

            //
            sendBuffer[20] = net.ServerLastNode;//PLC ip地址的最后一个节点
            sendBuffer[21] = 0x00;//DN2
            sendBuffer[22] = 0x02;//SNA 
            sendBuffer[23] = net.ClientLastNode;//上位机ip地址的最后一个节点

            //
            sendBuffer[24] = 0x00;//SA2
            sendBuffer[25] = (byte)commandId;//SID -> 命令编号
            sendBuffer[26] = 0x01;//读取命令
            sendBuffer[27] = 0x01;//读取长度

            sendBuffer[28] = Area;//区域
            sendBuffer[29] = (byte)((byte)(WordAddress >> 8) & 0xFF);//字地址高8位
            sendBuffer[30] = (byte)(WordAddress & 0xFF);//字地址低8位
            sendBuffer[31] = BitAddress;//位地址 0~15

            sendBuffer[32] = (byte)((byte)(Length >> 8) & 0xFF);//长度位移8个，长度进行相位与
            sendBuffer[33] = (byte)(Length & 0xFF);//长度低8位

            // 将数据写入到发送byte【】后面
            int index = 0;
            for (int i = 0; i < sendBuffer.Length; i++)
            {
                sendBuffer[i] = dataArray[index++];
            }
            return sendBuffer;
        }
        /// <summary>
        /// 获取下发指令的数据长度字节数据
        /// </summary>
        /// <param name="dataByteLength"></param>
        /// <returns></returns>
        private byte[] GetByteLengt(int dataByteLength)
        {
            return BitConverter.GetBytes(dataByteLength).Reverse().ToArray();
        }
    }
   

}
